package com.yuandian.ops.workbench.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.management.entity.ConfBusiness;
import com.yuandian.api.management.feign.RemoteBusinessService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.ops.workbench.enums.AlarmIndicatorCodeEnum;
import com.yuandian.ops.workbench.enums.BusiTypeEnum;
import com.yuandian.ops.workbench.enums.DataTypeEnum;
import com.yuandian.ops.workbench.mapper.RealTimeAlarmMapper;
import com.yuandian.ops.workbench.po.AlarmListParams;
import com.yuandian.ops.workbench.po.NewestAlarmParams;
import com.yuandian.ops.workbench.po.RealTimeAlarmParams;
import com.yuandian.ops.workbench.service.IRealTimeAlarmService;
import com.yuandian.ops.workbench.vo.*;
import com.yuandian.utils.BeanUtils;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.poi.ExcelTitleUtils;
import com.yuandian.utils.poi.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 实时告警service
 * <p>
 *
 * @author linshihe
 * @date 2021/10/25
 * @since 1.0.0
 */
@Service
@Slf4j
public class RealTimeAlarmServiceImpl implements IRealTimeAlarmService {

	@Autowired
	private RealTimeAlarmMapper realTimeAlarmMapper;

	@Autowired
	private RemoteBusinessService remoteBusinessService;

	/**
	 * 观察对象描述中文转换
	 */
	private static final Map<Integer, String> dataTypeDescribeMap = new HashMap<>();

	private static final Map<String, String> alarmIndicatorCodeMap = new HashMap<>();

	static {
		dataTypeDescribeMap.put(DataTypeEnum.commonSteps.getDataType(), DataTypeEnum.commonSteps.getDesc());
		dataTypeDescribeMap.put(DataTypeEnum.commonInterface.getDataType(), DataTypeEnum.commonInterface.getDesc());
		dataTypeDescribeMap.put(DataTypeEnum.HIGH.getDataType(), DataTypeEnum.HIGH.getDesc());
		dataTypeDescribeMap.put(DataTypeEnum.OFTEN.getDataType(), DataTypeEnum.OFTEN.getDesc());
		dataTypeDescribeMap.put(DataTypeEnum.LOW.getDataType(), DataTypeEnum.LOW.getDesc());
		dataTypeDescribeMap.put(DataTypeEnum.IDLE.getDataType(), DataTypeEnum.IDLE.getDesc());

		alarmIndicatorCodeMap.put("BS_FAIL_RATE_10", "失败");
		alarmIndicatorCodeMap.put("BS_FAIL_RATE_20", "响应慢");
	}

	/**
	 * 获取最新告警列表（BPM4.0）
	 *
	 * @param params 请求参数
	 * @return 结果集
	 */

	@Override
	public PageDataInfo getNewestAlarmList(NewestAlarmParams params) {
		Page<NewestAlarmVo> page = new Page<>(params.getPageNum(), params.getPageSize());

		// 如果前端是根据 '笔数' 字段进行排序，那么此处需要查询全部再手动分页
		if (params.getOrderByColumn() != null && "records".equalsIgnoreCase(params.getOrderByColumn())) {
			page = new Page<>(1, -1);
		}

		int index = 1;
		List<NewestAlarmVo> list = new ArrayList<>();
		// 1.查询数据(需要判断是否是由大屏首页发起的请求，若是，则需要针对相同的业务/步骤/接口 进行去重)
		if (params.getIsHomePage() == 1) {

			// 进入这里表示该接口是由大屏首页发起
			list = realTimeAlarmMapper.getNewestDiffAlarmList(page, params);

		} else {
			list = realTimeAlarmMapper.getNewestAlarmList(page, params);
		}


		if (!CollectionUtils.isEmpty(list)) {
			List<String> groupIdList = list.stream().map(NewestAlarmVo::getGroupId).collect(Collectors.toList());

			for (NewestAlarmVo alarmVo : list) {

				// 2.回填观察对象值中文
				alarmVo.setObservationObjectName(dataTypeDescribeMap.get(alarmVo.getDataType()));

				// 3.回填笔数
				if ("BS_FAIL_RATE_10".equalsIgnoreCase(params.getAlarmIndicatorCode())) {
					alarmVo.setRecords(alarmVo.getFailCount());
				} else if ("BS_FAIL_RATE_20".equalsIgnoreCase(params.getAlarmIndicatorCode())) {
					alarmVo.setRecords(alarmVo.getDealTimeAlarmCount());
				}

				// 4.如果是下载的话则需要回填 序号和补充百分比
				if (params.getPageSize() == -1) {
					// 下载Excel需要回填序号
					alarmVo.setIndex(index++);

					// 3.计算健康度、失败率、响应慢等指标
					alarmVo.setHealthRate(alarmVo.getHealthRate() + "%");
					alarmVo.setFailRate(alarmVo.getFailRate() + "%");
					alarmVo.setDealTimeAlarmRate(alarmVo.getDealTimeAlarmRate() + "%");
				}
			}
		}

		// 如果前端是根据 '笔数' 字段进行排序，那么此处需要查询全部再手动分页
		if (params.getOrderByColumn() != null && "records".equalsIgnoreCase(params.getOrderByColumn())) {

			Comparator<NewestAlarmVo> comparator = Comparator.comparing(NewestAlarmVo::getRecords);
			if (params.getOrderByColumn() != null && "ASC".equalsIgnoreCase(params.getIsAsc())) {
				list = list.stream().sorted(comparator).collect(Collectors.toList());
			} else if (params.getOrderByColumn() != null && "DESC".equalsIgnoreCase(params.getIsAsc())) {
				comparator = comparator.reversed();
				list = list.stream().sorted(comparator).collect(Collectors.toList());
			}

			if (params.getPageSize() != -1) {
				// 对数据进行聚合后进行手动分页
				int pNum = Long.valueOf(params.getPageNum()).intValue();
				int pSize = Long.valueOf(params.getPageSize()).intValue();
				long total = list.size();
				int from = (pNum - 1) * pSize;
				long to = (long) pNum * pSize;
				if (to > total) {
					to = total;
				}
				return new PageDataInfo(total, list.subList(from, (int) to));

			} else {
				// 如果是下载的话就不需要手动分页，直接返回全部即可
				return new PageDataInfo(0, list);
			}

		} else {
			// 6.返回结果集
			return new PageDataInfo(page, list);
		}
	}

	/**
	 * 获取最新告警Excel列表（BPM4.0）
	 *
	 * @param params 请求参数
	 * @return 结果集
	 */
	@Override
	public void getNewestAlarmListDownLoad(NewestAlarmParams params, HttpServletResponse response) throws IOException {

		String title = "最新" + ("BS_FAIL_RATE_10".equals(params.getAlarmIndicatorCode()) ? "失败" : "响应慢") + "业务告警";
		String fileName = title + System.currentTimeMillis();
		List<String> headParamsList = new ArrayList<>();
		headParamsList.add(title);
		String formTitleName = ExcelTitleUtils.formTitleName(headParamsList, params.getStartTime(), params.getEndTime());

		// 2. 查询要导出的数据
		params.setPageNum(1);
		params.setPageSize(-1);
		PageDataInfo pageDataInfo = BeanUtils.cast(getNewestAlarmList(params));
		String alarmIndicatorCode = params.getAlarmIndicatorCode();

		// 3.表单大标题合并单元格
		List<List<String>> headList = new ArrayList<>();
		List<String> titleList = new ArrayList<>();

		if (AlarmIndicatorCodeEnum.fail.getIndicatorType().equals(alarmIndicatorCode)) {
			// 最新失败率比例下载
			List<NewestFailAlarmDownVo> list1 = BeanUtils.convert(pageDataInfo.getData(), NewestFailAlarmDownVo.class);

			titleList = Arrays.asList("序号", "推送时间", "系统名称", "业务名称", "共用步骤/接口", "观察对象", "失败率", "笔数");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(NewestFailAlarmDownVo.class, fileName, title, list1, headList, response);

		} else if (AlarmIndicatorCodeEnum.dealTime.getIndicatorType().equals(alarmIndicatorCode)) {
			// 最新响应慢告警下载
			List<NewestDealTimeAlarmDownVo> list2 = BeanUtils.convert(pageDataInfo.getData(), NewestDealTimeAlarmDownVo.class);

			titleList = Arrays.asList("序号", "推送时间", "系统名称", "业务名称", "共用步骤/接口", "观察对象", "响应慢比例", "笔数");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(NewestDealTimeAlarmDownVo.class, fileName, title, list2, headList, response);
		}
	}

	/**
	 * 获取告警事件档案总览列表(BPM 4.0)
	 *
	 * @param params 请求参数
	 */
	@Override
	public PageDataInfo getAlarmEventFileList(NewestAlarmParams params) {
		Page<AlarmEventFileVo> page = new Page<>(params.getPageNum(), params.getPageSize());

		// 0.如果查共用步骤则不需要带上系统和业务编码
		if (!CollectionUtils.isEmpty(params.getStepCodeList())) {
			params.setSystemId(null);
			params.setBusinessCodeList(null);
		}

		// 1.查询数据
		List<AlarmEventFileVo> list = realTimeAlarmMapper.getAlarmEventFileList(page, params);
		int index = 1;
		for (AlarmEventFileVo alarmVo : list) {
			// 2.下载Excel需要回填序号
			alarmVo.setIndex(index++);
			// 3.回填观察对象值中文
			alarmVo.setObservationObjectName(dataTypeDescribeMap.get(alarmVo.getDataType()));
		}

		return new PageDataInfo(page, list);
	}


	/**
	 * 获取告警事件档案详情列表(BPM 4.0)
	 *
	 * @param params 请求参数
	 */
	@Override
	public PageDataInfo getAlarmEventFileDetailList(NewestAlarmParams params) {
		Page<AlarmEventFileDetailVo> page = new Page<>(params.getPageNum(), params.getPageSize());

		// 1.查询数据
		List<AlarmEventFileDetailVo> list = realTimeAlarmMapper.getAlarmEventFileDetailList(page, params);

		int index = 1;
		for (AlarmEventFileDetailVo alarmVo : list) {
			if (params.getPageSize() == -1) {
				// 2.下载Excel需要回填序号
				alarmVo.setIndex(index++);
			}

			// 3.回填观察对象值中文
			alarmVo.setObservationObjectName(dataTypeDescribeMap.get(alarmVo.getDataType()));
			alarmVo.setAlarmIndicatorCodeName(alarmIndicatorCodeMap.get(alarmVo.getAlarmIndicatorCode()));
			alarmVo.setHealthRate(alarmVo.getHealthRate() + "%");

			if ("BS_FAIL_RATE_10".equalsIgnoreCase(params.getAlarmIndicatorCode())) {
				alarmVo.setFailCountOrDealTimeCount(alarmVo.getFailCount());

			} else if ("BS_FAIL_RATE_20".equalsIgnoreCase(params.getAlarmIndicatorCode())) {
				alarmVo.setFailCountOrDealTimeCount(alarmVo.getDealTimeAlarmCount());
			}
		}

		return new PageDataInfo(page, list);
	}

	/**
	 * 获取告警事件档案详情列表Excel（BPM4.0）
	 *
	 * @param params 请求参数
	 * @return 结果集
	 */
	@Override
	public void getAlarmEventFileDetailListDownLoad(NewestAlarmParams params, HttpServletResponse response) throws IOException {
		String title = "告警业务事件档案详情表";
		String fileName = title + System.currentTimeMillis();
		List<String> headParamsList = new ArrayList<>();
		headParamsList.add(title);
		if (params.getDataType() != null && (params.getDataType() == 3 || params.getDataType() == 4)) {
			headParamsList.add(params.getStepNameOrCode());
		} else {
			headParamsList.add(params.getSystemName());
			headParamsList.add(params.getBusinessName());
		}
		headParamsList.add(params.getObservationObjectName());
		headParamsList.add(params.getDataTypeName());

		String formTitleName = ExcelTitleUtils.formTitleName(headParamsList, params.getStartTime(), params.getEndTime());

		// 2. 查询要导出的数据
		params.setPageNum(1);
		params.setPageSize(-1);
		PageDataInfo pageDataInfo = BeanUtils.cast(getAlarmEventFileDetailList(params));

		// 3.表单大标题合并单元格
		List<List<String>> headList = new ArrayList<>();
		List<String> titleList = new ArrayList<>();

		// 4.获取数据
		List<AlarmEventFileDetailVo> list1 = BeanUtils.convert(pageDataInfo.getData(), AlarmEventFileDetailVo.class);

		// 5.设置Excel列字段
		titleList = Arrays.asList("序号", "起始观察时间", "观察周期", "访问量", "告警访问量", "失败访问量", "健康度");

		titleList.forEach(s -> {
			List<String> childHeadList = new ArrayList<>();
			childHeadList.add(formTitleName);
			childHeadList.add(s);
			headList.add(childHeadList);
		});

		ExcelUtil.writeExcel(AlarmEventFileDetailVo.class, fileName, title, list1, headList, response);
	}

	/**
	 * 获取告警事件档案总览列表Excel（BPM4.0）
	 *
	 * @param params 请求参数
	 * @return 结果集
	 */
	@Override
	public void getAlarmEventFileListDownLoad(NewestAlarmParams params, HttpServletResponse response) throws IOException {
		String title = "告警业务事件档案总览表";
		String fileName = title + System.currentTimeMillis();
		List<String> headParamsList = new ArrayList<>();
		headParamsList.add(title);
		String formTitleName = ExcelTitleUtils.formTitleName(headParamsList, params.getStartTime(), params.getEndTime());

		// 2. 查询要导出的数据
		params.setPageNum(1);
		params.setPageSize(-1);
		PageDataInfo pageDataInfo = BeanUtils.cast(getAlarmEventFileList(params));

		// 3.表单大标题合并单元格
		List<List<String>> headList = new ArrayList<>();
		List<String> titleList = new ArrayList<>();

		// 4.获取数据
		List<AlarmEventFileVo> list1 = BeanUtils.convert(pageDataInfo.getData(), AlarmEventFileVo.class);

		// 5.设置Excel列字段
		titleList = Arrays.asList("序号", "系统名称", "业务名称", "共用步骤名称", "观察对象", "总事件档案数", "失败事件档案数", "响应慢事件档案数");

		titleList.forEach(s -> {
			List<String> childHeadList = new ArrayList<>();
			childHeadList.add(formTitleName);
			childHeadList.add(s);
			headList.add(childHeadList);
		});

		ExcelUtil.writeExcel(AlarmEventFileVo.class, fileName, title, list1, headList, response);
	}

	/**
	 * 二级-首页右下角最新健康度告警列表-更多
	 *
	 * @param params 请求参数
	 */
	@Override
	public PageDataInfo getHealthAlarmList(NewestAlarmParams params) {
		Page<AlarmHealthVo> page = new Page<>(params.getPageNum(), params.getPageSize());
		params.setOrderByColumn("pushTime".equals(params.getOrderByColumn()) ? "cycleTime" : params.getOrderByColumn());
		List<AlarmHealthVo> list = realTimeAlarmMapper.getHealthAlarmList(page, params);

		int index = 1; // 初始化用于下载Excel的序号
		for (AlarmHealthVo alarmVo : list) {

			// 回填观察对象值中文
			alarmVo.setObservationObjectName(dataTypeDescribeMap.get(alarmVo.getDataType()));
			alarmVo.setStartTime(alarmVo.getCycleTime());
			alarmVo.setEndTime(alarmVo.getCycleTime());
			alarmVo.setAlarmIndicatorCode(AlarmIndicatorCodeEnum.healthy.getIndicatorType());

			// params.getPageSize() == -1 表示是下载调的接口，需要回填序号和'%'
			if (params.getPageSize() == -1) {
				// 下载Excel需要回填序号
				alarmVo.setIndex(index++);
				alarmVo.setHealthRate(alarmVo.getHealthRate() + "%");
				alarmVo.setFailRate(alarmVo.getFailRate() + "%");
			}
		}

		return new PageDataInfo(page, list);
	}

	/**
	 * 获取告警事件档案总览列表Excel（BPM4.0）
	 *
	 * @param params 请求参数
	 * @return 结果集
	 */
	@Override
	public void getHealthAlarmListDownLoad(NewestAlarmParams params, HttpServletResponse response) throws IOException {
		String title = "最新健康度业务告警";
		String fileName = title + System.currentTimeMillis();
		List<String> headParamsList = new ArrayList<>();
		headParamsList.add(title);
		String formTitleName = ExcelTitleUtils.formTitleName(headParamsList, params.getStartTime(), params.getEndTime());

		// 2. 查询要导出的数据
		params.setPageNum(1);
		params.setPageSize(-1);
		PageDataInfo pageDataInfo = BeanUtils.cast(getHealthAlarmList(params));

		// 3.表单大标题合并单元格
		List<List<String>> headList = new ArrayList<>();
		List<String> titleList = new ArrayList<>();

		// 4.获取数据
		List<AlarmHealthVo> list1 = BeanUtils.convert(pageDataInfo.getData(), AlarmHealthVo.class);

		// 5.设置Excel列字段
		titleList = Arrays.asList("序号", "告警时间", "系统名称", "业务名称", "共用步骤/接口", "观察对象", "健康度", "失败率");

		titleList.forEach(s -> {
			List<String> childHeadList = new ArrayList<>();
			childHeadList.add(formTitleName);
			childHeadList.add(s);
			headList.add(childHeadList);
		});

		ExcelUtil.writeExcel(AlarmHealthVo.class, fileName, title, list1, headList, response);
	}


	/**
	 * 统计 dws_business_status_alarm 表中指定 groupId 对应的数据条数, Map<groupID, 对应数据条数>
	 *
	 * @param groupIdList 事件ID列表
	 */
	private Map<String, Integer> getCountByGroupId(List<String> groupIdList) {
		Map<String, Integer> map = new HashMap<>();
		List<NewestAlarmVo> list = realTimeAlarmMapper.getCountByGroupId(groupIdList);
		if (!CollectionUtils.isEmpty(list)) {
			map = list.stream().collect(
					Collectors.toMap(NewestAlarmVo::getGroupId, NewestAlarmVo::getRecords, (key1, key2) -> key2)
			);
		}
		return map;
	}



	/**
	 * 获取告警详情列表
	 * @param params 请求参数
	 * @return
	 */
	@Override
	public PageDataInfo getRealTimeAlarmDetailList(RealTimeAlarmParams params) {
		PageDataInfo pageDataInfo = null;

		String alarmIndicatorCode = params.getAlarmIndicatorCode();
		if (AlarmIndicatorCodeEnum.fail.getIndicatorType().equals(alarmIndicatorCode)) {
			pageDataInfo = getBusinessFailDetailList(getAlarmListParams(params));
		}
		if (AlarmIndicatorCodeEnum.dealTime.getIndicatorType().equals(alarmIndicatorCode)) {
			pageDataInfo = businessAlarmDetailList(getAlarmListParams(params));
		}
		if (AlarmIndicatorCodeEnum.healthy.getIndicatorType().equals(alarmIndicatorCode)) {
			pageDataInfo = businessAlarmDetailList(getAlarmListParams(params));
		}

		return pageDataInfo;
	}


	/**
	 * 健康度低业务告警详情列表
	 *
	 * @param params 请求参数
	 * @return 响应慢业务告警详情列表
	 */
	public PageDataInfo getBusinessFailDetailList(AlarmListParams params) {
		Page<BusiStatusAlarmVo> page = new Page<>(params.getPageNum(), params.getPageSize());
		List<BusiStatusAlarmVo> list = realTimeAlarmMapper.getBusinessFailDetailList(page, params);

		return new PageDataInfo(page, list);
	}

	/**
	 * 健康度低、响应慢业务告警详情列表
	 *
	 * @param params 请求参数
	 * @return 响应慢业务告警详情列表
	 */
	public PageDataInfo businessAlarmDetailList(AlarmListParams params) {
		Page<AlarmDetailListVo> page = new Page<>(params.getPageNum(), params.getPageSize());
		List<AlarmDetailListVo> list = realTimeAlarmMapper.businessAlarmDetailList(page, params);

		return new PageDataInfo(page, list);
	}



	private AlarmListParams getAlarmListParams(RealTimeAlarmParams params) {
		AlarmListParams alarmListParams = new AlarmListParams();

		if (params != null) {
			alarmListParams.setSystemId(params.getSystemId());
			alarmListParams.setBusinessCode(params.getBusinessCode());
			alarmListParams.setStartTime(params.getStartTime());
			alarmListParams.setEndTime(params.getEndTime());
			alarmListParams.setPageNum(params.getPageNum());
			alarmListParams.setPageSize(params.getPageSize());
			alarmListParams.setOrderByColumn(params.getOrderByColumn());
			alarmListParams.setIsAsc(params.getIsAsc());
			alarmListParams.setAlarmIndicatorCode(params.getAlarmIndicatorCode());
		}
		return alarmListParams;
	}



	/**
	 * 获取业务健康度状况-业务各类告警次数概况
	 * @param params 请求参数
	 * @return
	 */
	@Override
	public R<Object> getBusinessAlarmCountList(RealTimeAlarmParams params) {

		params.setTableName("ads_business_detail_stat_m");
		// 结果集
		List<BusinessAllAlarmVo> resList = new ArrayList<>();
		// 根据 健康度 排序
		List<BusinessAllAlarmVo> healthAllList = realTimeAlarmMapper.getAllBusinessListHealth(params);
		List<BusinessAllAlarmVo> AlarmAllList = realTimeAlarmMapper.getAllBusinessListAlarm(params);
		if (healthAllList !=  null && AlarmAllList != null) {
			for (BusinessAllAlarmVo healthVO : healthAllList) {
				for (BusinessAllAlarmVo alarmVo : AlarmAllList) {
					if (healthVO.getSystemId().equals(alarmVo.getSystemId())
							&& healthVO.getBusinessCode().equals(alarmVo.getBusinessCode())) {

						healthVO.setAlarmNum(alarmVo.getAlarmNum());
						healthVO.setFailAlarmCount(alarmVo.getFailAlarmCount());
						healthVO.setDealTimeAlarmCount(alarmVo.getDealTimeAlarmCount());
						healthVO.setHealthAlarmCount(alarmVo.getHealthAlarmCount());
						resList.add(healthVO);
						break;
					}
				}
			}
		}
		// 判断是否需要进行关键业务过滤
		if (BusiTypeEnum.keyBusi.getBusinessType() == params.getBusiType()) {
			// 过滤非关键业务
			resList = getKeyBusinessList(resList);
		}
		int total = resList.size();
		// 对数据进行排序
		List<BusinessAllAlarmVo> list = getDataSort(params, resList);

		return R.ok(new PageDataInfo(total, list));
	}


	/**
	 * 获取关键业务
	 * @param list 待过滤列表
	 * @return	结果集
	 */
	private List<BusinessAllAlarmVo> getKeyBusinessList(List<BusinessAllAlarmVo> list) {
		List<BusinessAllAlarmVo> resList = new ArrayList<>();

		Optional<R<List<ConfBusiness>>> result = Optional.empty();
		try {
			long sTime = System.currentTimeMillis();
			result = Optional.of(remoteBusinessService.queryKeyBusiness());
			log.info("[运维工作台]-[远程调用-后台配置服务]-[获取关键业务列表]-耗时: {} MS", System.currentTimeMillis() - sTime);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("[运维工作台]-[远程调用-后台配置服务]-[获取关键业务列表]报错: {}" + e.getMessage());
		}

		Map<String, String> map = result.map(R::getData)
				.orElse(Collections.emptyList())
				.stream()
				.collect(Collectors.toMap(ConfBusiness::getBusinessCode,
						ConfBusiness::getName));

		resList = list.stream()
				.filter(businessAlarmTopVo -> StringUtils.isNotEmpty(map.get(businessAlarmTopVo.getBusinessCode())))
				.collect(Collectors.toList());

//		return resList;	TODO 目前配置表尚未配置关键业务，后续配置了需要放开该注释
		return list;
	}


	/**
	 * 数据排序
	 * @param params	参数
	 * @param list	待处理列表
	 * @return	结果集
	 */
	public List<BusinessAllAlarmVo> getDataSort(RealTimeAlarmParams params, List<BusinessAllAlarmVo> list) {
		// 默认以 健康度降序 排序
		if (StringUtils.isEmpty(params.getOrderByColumn()) || StringUtils.isEmpty(params.getIsAsc())) {
			params.setOrderByColumn("healthRate");
			params.setIsAsc("desc");
		}
		Comparator<BusinessAllAlarmVo> comparator = null;
		switch (params.getOrderByColumn()) {
			case "healthRate" :
				comparator = Comparator.comparing(BusinessAllAlarmVo::getHealthRate);
				break;
			case "alarmNum" :
				comparator = Comparator.comparing(BusinessAllAlarmVo::getAlarmNum);
				break;
			case "healthAlarmCount" :
				comparator = Comparator.comparing(BusinessAllAlarmVo::getHealthAlarmCount);
				break;
			case "failAlarmCount" :
				comparator = Comparator.comparing(BusinessAllAlarmVo::getFailAlarmCount);
				break;
			case "dealTimeAlarmCount" :
				comparator = Comparator.comparing(BusinessAllAlarmVo::getDealTimeAlarmCount);
				break;
		}
		if ("desc".equalsIgnoreCase(params.getIsAsc())) {
			comparator = comparator.reversed();
		}

		list = list.stream().sorted(comparator).collect(Collectors.toList());
		int pNum = Long.valueOf(params.getPageNum()).intValue();
		int pSize = Long.valueOf(params.getPageSize()).intValue();
		int total = list.size();
		int from = (pNum - 1) * pSize;
		int to = pNum * pSize;
		if (to > total) {
			to = total;
		}
		return list.subList(from, to);
	}



	/**
	 * 导出告警详情列表
	 * @param params 请求参数
	 * @return
	 */
	@Override
	public void getRealTimeAlarmDetailListExport(RealTimeAlarmParams params, HttpServletResponse response) throws IOException {

		String systemName = getSystemName(params.getSystemName());
		String businessName = getBusinessName(params.getBusinessName());
		String alarmIndicatorName = getAlarmIndicatorName(params.getAlarmIndicatorName());
		String title = alarmIndicatorName  + "数据总览表";
		String fileName = title + System.currentTimeMillis();
		List<String> headParamsList = new ArrayList<>();
		headParamsList.add(title);
		headParamsList.add(systemName);
		headParamsList.add(businessName);
		headParamsList.add(alarmIndicatorName);
		String formTitleName = ExcelTitleUtils.formTitleName(headParamsList, params.getStartTime(), params.getEndTime());

		// 2. 查询要导出的数据
		params.setPageNum(1);
		params.setPageSize(1000000L);
		PageDataInfo pageDataInfo = BeanUtils.cast(getRealTimeAlarmDetailList(params));
		String alarmIndicatorCode = params.getAlarmIndicatorCode();
		// 3.表单大标题合并单元格
		List<List<String>> headList = new ArrayList<>();
		List<String> titleList = new ArrayList<>();
		int index = 1;
		if (AlarmIndicatorCodeEnum.fail.getIndicatorType().equals(alarmIndicatorCode)) {

			List<BusiStatusAlarmVo> list1 = BeanUtils.cast(pageDataInfo.getData());
			for (BusiStatusAlarmVo busiStatusAlarmVo : list1) {
				busiStatusAlarmVo.setFailRate(busiStatusAlarmVo.getFailRate() == null ? "" : (busiStatusAlarmVo.getFailRate() + "%"));
				busiStatusAlarmVo.setIndex(index++);
				// 把（yyyy-MM-dd HH:mm:ss.0）去掉最后的 .0
//				busiStatusAlarmVo.setCycleTime(DateTool.interceptionTime(busiStatusAlarmVo.getCycleTime()));
			}
			titleList = Arrays.asList("序号", "告警时间", "总访问量", "告警访问量", "失败访问量", "失败率");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(BusiStatusAlarmVo.class, fileName, title, list1, headList, response);

		}else if (AlarmIndicatorCodeEnum.dealTime.getIndicatorType().equals(alarmIndicatorCode)) {

			List<AlarmDetailListVo> list2 = BeanUtils.cast(pageDataInfo.getData());
			for (AlarmDetailListVo alarmDetailListVo : list2) {
				alarmDetailListVo.setFailRate(alarmDetailListVo.getFailRate() == null ? "" : (alarmDetailListVo.getFailRate() + "%"));
				alarmDetailListVo.setDealTimeAlarmRate(alarmDetailListVo.getDealTimeAlarmRate() == null ? "" : (alarmDetailListVo.getDealTimeAlarmRate() + "%"));
				alarmDetailListVo.setIndex(index++);
				// 把（yyyy-MM-dd HH:mm:ss.0）去掉最后的 .0
//				alarmDetailListVo.setCycleTime(DateTool.interceptionTime(alarmDetailListVo.getCycleTime()));
			}
			titleList = Arrays.asList("序号", "告警时间", "总访问量", "告警访问量", "响应慢访问量", "失败访问量", "失败率", "响应慢比例");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(AlarmDetailListVo.class, fileName, title, list2, headList, response);

		}else if (AlarmIndicatorCodeEnum.healthy.getIndicatorType().equals(alarmIndicatorCode)) {

			List<AlarmDetailListVo> list3 = BeanUtils.cast(pageDataInfo.getData());
			List<HealthAlarmListVo> healthList = getHealthList(list3);
			for (HealthAlarmListVo healthAlarmListVo : healthList) {
				healthAlarmListVo.setFailRate(healthAlarmListVo.getFailRate() == null ? "" : (healthAlarmListVo.getFailRate() + "%"));
				healthAlarmListVo.setHealthRate(healthAlarmListVo.getHealthRate() == null ? "" : (healthAlarmListVo.getHealthRate() + "%"));
				healthAlarmListVo.setIndex(index++);
				// 把（yyyy-MM-dd HH:mm:ss.0）去掉最后的 .0
//				healthAlarmListVo.setCycleTime(DateTool.interceptionTime(healthAlarmListVo.getCycleTime()));
			}
			titleList = Arrays.asList("序号", "告警时间", "总访问量", "告警访问量", "失败访问量", "失败率", "健康度");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(HealthAlarmListVo.class, fileName, title, healthList, headList, response);
		}

	}


	/**
	 *  修改list的实体类
	 */
	private List<HealthAlarmListVo> getHealthList(List<AlarmDetailListVo> list3) {
		List<HealthAlarmListVo> healthList = new ArrayList<>();
		if (list3 != null && list3.size() > 0) {
			for (AlarmDetailListVo alarmDetailListVo : list3) {
				HealthAlarmListVo healthAlarmListVo = BeanUtils.convert(alarmDetailListVo, HealthAlarmListVo.class, null);
				healthList.add(healthAlarmListVo);
			}
		}
		return healthList;
	}


	/**
	 * 格式化系统名称
	 */
	public static String getSystemName(String systemName) {
		return systemName == null ? "未知系统" : (systemName + "系统");
	}

	/**
	 * 格式化业务名称
	 */
	public static String getBusinessName(String businessName) {
		return businessName == null ? "未知业务" : (businessName + "业务");
	}

	/**
	 * 格式化告警指标名称
	 */
	public static String getAlarmIndicatorName(String alarmIndicatorName) {
		return alarmIndicatorName == null ? "未知告警" : alarmIndicatorName;
	}


}
